package com.apollo.android.um.imp;

import android.app.Notification;
import android.content.Context;

import com.apollo.android.um.anno.notice.CustomMessage;
import com.apollo.android.um.anno.notice.CustomNotification;
import com.apollo.android.um.anno.notice.NotificationMessage;
import com.apollo.android.um.constants.Constants;
import com.apollo.android.um.utils.LogUtils;
import com.apollo.android.utils.Helper;
import com.apollo.android.utils.ResUtils;
import com.umeng.message.UmengMessageHandler;
import com.umeng.message.entity.UMessage;

import java.lang.reflect.Method;

public class UMessageHandlerImp extends UmengMessageHandler {

    private Method customMessageMethod;
    private Method notificationMessageMethod;
    private Method notificationMethod;

    private boolean dealWithCustomMessage(Method method, Context context, UMessage uMessage) {
        try {
            CustomMessage customMessage = method.getAnnotation(CustomMessage.class);
            if (customMessage != null) {
                Class[] paramTypes = method.getParameterTypes();
                if (paramTypes != null && paramTypes.length == 2 && paramTypes[0] == Context.class && paramTypes[1] == UMessage.class) {
                    method.invoke(null, context, uMessage);
                    return true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public void dealWithCustomMessage(Context context, UMessage uMessage) {
        LogUtils.log("dealWithCustomMessage");
        if (customMessageMethod != null && dealWithCustomMessage(customMessageMethod, context, uMessage)) {
            return;
        }
        customMessageMethod = null;
        final String registerClassName = ResUtils.getString(Constants.CLASS_MESSAGE);
        if (Helper.isNotEmpty(registerClassName)) {
            try {
                Class registerClass = Class.forName(registerClassName);
                Method[] methods = registerClass.getDeclaredMethods();
                if (methods != null) {
                    for (Method method : methods) {
                        if (dealWithCustomMessage(method, context, uMessage)) {
                            customMessageMethod = method;
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private boolean dealWithNotificationMessage(Method method, Context context, UMessage uMessage) {
        try {
            NotificationMessage notificationMessage = method.getAnnotation(NotificationMessage.class);
            if (notificationMessage != null) {
                Class[] paramTypes = method.getParameterTypes();
                if (paramTypes != null && paramTypes.length == 2 && paramTypes[0] == Context.class && paramTypes[1] == UMessage.class) {
                    method.invoke(null, context, uMessage);
                    return true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public void dealWithNotificationMessage(Context context, UMessage uMessage) {
        if (notificationMessageMethod == null || !dealWithNotificationMessage(notificationMessageMethod, context, uMessage)) {
            final String registerClassName = ResUtils.getString(Constants.CLASS_NOTIFICATION);
            if (Helper.isNotEmpty(registerClassName)) {
                try {
                    Class registerClass = Class.forName(registerClassName);
                    Method[] methods = registerClass.getDeclaredMethods();
                    if (methods != null) {
                        for (Method method : methods) {
                            if (dealWithNotificationMessage(method, context, uMessage)) {
                                notificationMessageMethod = method;
                                break;
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        super.dealWithNotificationMessage(context, uMessage);
    }

    private Notification getNotification(Method method, Context context, UMessage uMessage) {
        try {
            CustomNotification customNotification = method.getAnnotation(CustomNotification.class);
            if (customNotification != null) {
                Class[] paramTypes = method.getParameterTypes();
                if (paramTypes != null && paramTypes.length == 2 && paramTypes[0] == Context.class && paramTypes[1] == UMessage.class) {
                    Object object = method.invoke(null, context, uMessage);
                    if (object instanceof Notification) {
                        return (Notification) object;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Notification getNotification(Context context, UMessage uMessage) {
        LogUtils.log("getNotification");
        if (notificationMethod != null) {
            final Notification notification = getNotification(notificationMethod, context, uMessage);
            if (notification != null) {
                return notification;
            }
        }
        final String registerClassName = ResUtils.getString(Constants.CLASS_CUSTOM_NOTIFICATION);
        if (Helper.isNotEmpty(registerClassName)) {
            try {
                Class registerClass = Class.forName(registerClassName);
                Method[] methods = registerClass.getDeclaredMethods();
                if (methods != null) {
                    for (Method method : methods) {
                        final Notification notification = getNotification(method, context, uMessage);
                        if (notification != null) {
                            notificationMethod = method;
                            return notification;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return super.getNotification(context, uMessage);
    }

}
